/*
 *  GRUB Utilities --  Utilities for GRUB Legacy, GRUB2 and GRUB for DOS
 *  Copyright (C) 2007 Bean (bean123ch@gmail.com)
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct
{
  unsigned short code[4];
  char *name;
} key_tab_t;

key_tab_t key_table[] = {
  {{0x1E61, 0x1E41, 0x1E01, 0x1E00}, "A"},
  {{0x3062, 0x3042, 0x3002, 0x3000}, "B"},
  {{0x2E63, 0x2E43, 0x2E03, 0x2E00}, "C"},
  {{0x2064, 0x2044, 0x2004, 0x2000}, "D"},
  {{0x1265, 0x1245, 0x1205, 0x1200}, "E"},
  {{0x2166, 0x2146, 0x2106, 0x2100}, "F"},
  {{0x2267, 0x2247, 0x2207, 0x2200}, "G"},
  {{0x2368, 0x2348, 0x2308, 0x2300}, "H"},
  {{0x1769, 0x1749, 0x1709, 0x1700}, "I"},
  {{0x246A, 0x244A, 0x240A, 0x2400}, "J"},
  {{0x256B, 0x254B, 0x250B, 0x2500}, "K"},
  {{0x266C, 0x264C, 0x260C, 0x2600}, "L"},
  {{0x326D, 0x324D, 0x320D, 0x3200}, "M"},
  {{0x316E, 0x314E, 0x310E, 0x3100}, "N"},
  {{0x186F, 0x184F, 0x180F, 0x1800}, "O"},
  {{0x1970, 0x1950, 0x1910, 0x1900}, "P"},
  {{0x1071, 0x1051, 0x1011, 0x1000}, "Q"},
  {{0x1372, 0x1352, 0x1312, 0x1300}, "R"},
  {{0x1F73, 0x1F53, 0x1F13, 0x1F00}, "S"},
  {{0x1474, 0x1454, 0x1414, 0x1400}, "T"},
  {{0x1675, 0x1655, 0x1615, 0x1600}, "U"},
  {{0x2F76, 0x2F56, 0x2F16, 0x2F00}, "V"},
  {{0x1177, 0x1157, 0x1117, 0x1100}, "W"},
  {{0x2D78, 0x2D58, 0x2D18, 0x2D00}, "X"},
  {{0x1579, 0x1559, 0x1519, 0x1500}, "Y"},
  {{0x2C7A, 0x2C5A, 0x2C1A, 0x2C00}, "Z"},
  {{0x0231, 0x0221, 0x0000, 0x7800}, "1"},
  {{0x0332, 0x0340, 0x0300, 0x7900}, "2"},
  {{0x0433, 0x0423, 0x0000, 0x7A00}, "3"},
  {{0x0534, 0x0524, 0x0000, 0x7B00}, "4"},
  {{0x0635, 0x0625, 0x0000, 0x7C00}, "5"},
  {{0x0736, 0x075E, 0x071E, 0x7D00}, "6"},
  {{0x0837, 0x0826, 0x0000, 0x7E00}, "7"},
  {{0x0938, 0x092A, 0x0000, 0x7F00}, "8"},
  {{0x0A39, 0x0A28, 0x0000, 0x8000}, "9"},
  {{0x0B30, 0x0B29, 0x0000, 0x8100}, "0"},
  {{0x0C2D, 0x0C5F, 0x0C1F, 0x8200}, "-"},
  {{0x0D3D, 0x0D2B, 0x0000, 0x8300}, "="},
  {{0x1A5B, 0x1A7B, 0x1A1B, 0x1A00}, "["},
  {{0x1B5D, 0x1B7D, 0x1B1D, 0x1B00}, "]"},
  {{0x273B, 0x273A, 0x0000, 0x2700}, ";"},
  {{0x2827, 0x2822, 0x0000, 0x0000}, "'"},
  {{0x2960, 0x297E, 0x0000, 0x0000}, "`"},
  {{0x2B5C, 0x2B7C, 0x2B1C, 0x2600}, "\\"},
  {{0x332C, 0x333C, 0x0000, 0x0000}, ","},
  {{0x342E, 0x343E, 0x0000, 0x0000}, "."},
  {{0x352F, 0x353F, 0x0000, 0x0000}, "/"},
  {{0x3B00, 0x5400, 0x5E00, 0x6800}, "F1"},
  {{0x3C00, 0x5500, 0x5F00, 0x6900}, "F2"},
  {{0x3D00, 0x5600, 0x6000, 0x6A00}, "F3"},
  {{0x3E00, 0x5700, 0x6100, 0x6B00}, "F4"},
  {{0x3F00, 0x5800, 0x6200, 0x6C00}, "F5"},
  {{0x4000, 0x5900, 0x6300, 0x6D00}, "F6"},
  {{0x4100, 0x5A00, 0x6400, 0x6E00}, "F7"},
  {{0x4200, 0x5B00, 0x6500, 0x6F00}, "F8"},
  {{0x4300, 0x5C00, 0x6600, 0x7000}, "F9"},
  {{0x4400, 0x5D00, 0x6700, 0x7100}, "F10"},
  {{0x8500, 0x8700, 0x8900, 0x8B00}, "F11"},
  {{0x8600, 0x8800, 0x8A00, 0x8C00}, "F12"},
  {{0x0E08, 0x0E08, 0x0E7F, 0x0E00}, "BACKSPACE"},
  {{0x5300, 0x532E, 0x9300, 0xA300}, "DEL"},
  {{0x5000, 0x5032, 0x9100, 0xA000}, "DOWN"},
  {{0x4F00, 0x4F31, 0x7500, 0x9F00}, "END"},
  {{0x1C0D, 0x1C0D, 0x1C0A, 0xA600}, "ENTER"},
  {{0x011B, 0x011B, 0x011B, 0x0100}, "ESC"},
  {{0x4700, 0x4737, 0x7700, 0x9700}, "HOME"},
  {{0x5200, 0x5230, 0x9200, 0xA200}, "INS"},
  {{0x0000, 0x4C35, 0x8F00, 0x0000}, "KEY-5"},
  {{0x372A, 0x0000, 0x9600, 0x3700}, "KEY-*"},
  {{0x4A2D, 0x4A2D, 0x8E00, 0x4A00}, "KEY--"},
  {{0x4E2B, 0x4E2B, 0x0000, 0x4E00}, "KEY-+"},
  {{0x352F, 0x352F, 0x9500, 0xA400}, "KEY-/"},
  {{0x4B00, 0x4B34, 0x7300, 0x9B00}, "LEFT"},
  {{0x5100, 0x5133, 0x7600, 0xA100}, "PGDN"},
  {{0x4900, 0x4939, 0x8400, 0x9900}, "PGUP"},
  {{0x0000, 0x0000, 0x7200, 0x0000}, "PRTSC"},
  {{0x4D00, 0x4D36, 0x7400, 0x9D00}, "RIGHT"},
  {{0x3920, 0x3920, 0x3920, 0x3920}, "SPACE"},
  {{0x0F09, 0x0F00, 0x9400, 0xA500}, "TAB"},
  {{0x4800, 0x4838, 0x8D00, 0x9800}, "UP"},
  {{0x0000, 0x0000, 0x0000, 0x0000}, (void *) 0}
};

char *
str_upcase (char *str)
{
  int i;

  for (i = 0; str[i]; i++)
    if ((str[i] >= 'a') && (str[i] <= 'z'))
      str[i] -= 'a' - 'A';

  return str;
}

int
get_keycode (char *key)
{
  int idx, i;
  char *str;

  if ((key[0] == '0') && (key[1] == 'x'))
    {
      int code;

      code = strtoul (key, NULL, 0);
      return ((code <= 0) || (code >= 0xFFFF)) ? 0 : code;
    }
  str = key;
  str_upcase (str);
  idx = 0;
  if (!strncmp (str, "SHIFT-", 6))
    {
      idx = 1;
      str += 6;
    }
  else if (!strncmp (str, "CTRL-", 5))
    {
      idx = 2;
      str += 5;
    }
  else if (!strncmp (str, "ALT-", 4))
    {
      idx = 3;
      str += 4;
    }
  for (i = 0; key_table[i].name; i++)
    {
      if (!strcmp (str, key_table[i].name))
	return key_table[i].code[idx];
    }
  return 0;
}

static char keyname_buf[16];

char *
get_keyname (unsigned short code)
{
  int i;

  for (i = 0; key_table[i].name; i++)
    {
      int j;

      for (j = 0; j < 4; j++)
	{	 
	  if (key_table[i].code[j] == code)
	    {
	      char *p;
	      
	      switch (j)
		{
		case 0:
		  p = "";
		  break;
		case 1:
		  p = "shift-";
		  break;
		case 2:
		  p = "ctrl-";
		  break;
		case 3:
		  p = "alt-";
		  break;
		}

	      sprintf (keyname_buf, "%s%s", p, key_table[i].name);
	      return keyname_buf;
	    }
	}
    }

  sprintf (keyname_buf, "0x%x", code);
  return keyname_buf;
}
